<!DOCTYPE html>
<html lang="zh-CN" data-theme="light">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <meta name="generator" content="VuePress 2.0.0-beta.53" />
    <meta name="theme" content="VuePress Theme Hope" />
    <link rel="icon" href="/doc/images/favicon.ico"><title>第 3 章 类型全解 | AT 的文档库</title><meta name="description" content="At 的文档库，好记性不如烂笔头！">
    <style>
      :root {
        --bg-color: #fff;
      }

      html[data-theme="dark"] {
        --bg-color: #1d2025;
      }

      html,
      body {
        background: var(--bg-color);
      }
    </style>
    <script>
      const userMode = localStorage.getItem("vuepress-theme-hope-scheme");
      const systemDarkMode =
        window.matchMedia &&
        window.matchMedia("(prefers-color-scheme: dark)").matches;

      if (userMode === "dark" || (userMode !== "light" && systemDarkMode)) {
        document.querySelector("html").setAttribute("data-theme", "dark");
      }
    </script>
    <link rel="preload" href="/doc/assets/style.c3a4c10b.css" as="style" /><link rel="stylesheet" href="/doc/assets/style.c3a4c10b.css" />
    <link rel="modulepreload" href="/doc/assets/app.41440b49.js"><link rel="modulepreload" href="/doc/assets/第 3 章 类型全解.html.9ad8a3d4.js"><link rel="modulepreload" href="/doc/assets/_plugin-vue_export-helper.cdc0426e.js"><link rel="modulepreload" href="/doc/assets/第 3 章 类型全解.html.e4f1b931.js"><link rel="prefetch" href="/doc/assets/index.html.0bcc895f.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.c8df2167.js" as="script" /><link rel="prefetch" href="/doc/assets/Vue2.html.48e096c5.js" as="script" /><link rel="prefetch" href="/doc/assets/Vue3.html.324e646c.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.fb0ad0e0.js" as="script" /><link rel="prefetch" href="/doc/assets/第 1 章 导言.html.d6c662f8.js" as="script" /><link rel="prefetch" href="/doc/assets/第 2 章 TypeScript 概述.html.e976154a.js" as="script" /><link rel="prefetch" href="/doc/assets/第 4 章 函数.html.701a2968.js" as="script" /><link rel="prefetch" href="/doc/assets/第 5 章 类和接口.html.8988d546.js" as="script" /><link rel="prefetch" href="/doc/assets/第 6 章 类型进阶.html.45b313e3.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.a9dd6465.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.a3374cf8.js" as="script" /><link rel="prefetch" href="/doc/assets/面试题详解.html.c326eaaf.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.88582229.js" as="script" /><link rel="prefetch" href="/doc/assets/常见问题.html.e0f65550.js" as="script" /><link rel="prefetch" href="/doc/assets/扩展使用.html.87cccc41.js" as="script" /><link rel="prefetch" href="/doc/assets/掌握 GIT.html.c150b234.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.a3c2858b.js" as="script" /><link rel="prefetch" href="/doc/assets/面试题详解.html.9a53d157.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.101afd82.js" as="script" /><link rel="prefetch" href="/doc/assets/面试题详解.html.8224e1cd.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.54b5ca2d.js" as="script" /><link rel="prefetch" href="/doc/assets/基础掌握.html.d839cc53.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.80e4d5cc.js" as="script" /><link rel="prefetch" href="/doc/assets/基础掌握.html.9a178a04.js" as="script" /><link rel="prefetch" href="/doc/assets/扩展知识.html.3535ab30.js" as="script" /><link rel="prefetch" href="/doc/assets/项目搭建.html.e926587b.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.881e95b0.js" as="script" /><link rel="prefetch" href="/doc/assets/安装及使用.html.ba7314a3.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.f9509ce0.js" as="script" /><link rel="prefetch" href="/doc/assets/第 1 章.html.726a0bb9.js" as="script" /><link rel="prefetch" href="/doc/assets/第 2 章.html.38f55e7d.js" as="script" /><link rel="prefetch" href="/doc/assets/Controllers.html.6b27764c.js" as="script" /><link rel="prefetch" href="/doc/assets/Module.html.3849b10b.js" as="script" /><link rel="prefetch" href="/doc/assets/Providers.html.7d2793f1.js" as="script" /><link rel="prefetch" href="/doc/assets/404.html.c5de7dd9.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.86b08b0b.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.f4119260.js" as="script" /><link rel="prefetch" href="/doc/assets/Vue2.html.caf7eb18.js" as="script" /><link rel="prefetch" href="/doc/assets/Vue3.html.6dc23cf4.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.868f2c80.js" as="script" /><link rel="prefetch" href="/doc/assets/第 1 章 导言.html.9edf000e.js" as="script" /><link rel="prefetch" href="/doc/assets/第 2 章 TypeScript 概述.html.76b27e4d.js" as="script" /><link rel="prefetch" href="/doc/assets/第 4 章 函数.html.9115df00.js" as="script" /><link rel="prefetch" href="/doc/assets/第 5 章 类和接口.html.e392a0d1.js" as="script" /><link rel="prefetch" href="/doc/assets/第 6 章 类型进阶.html.1b5b864e.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.e5a75968.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.974654cf.js" as="script" /><link rel="prefetch" href="/doc/assets/面试题详解.html.ed3fa7a3.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.3b9ebcaa.js" as="script" /><link rel="prefetch" href="/doc/assets/常见问题.html.b427e39a.js" as="script" /><link rel="prefetch" href="/doc/assets/扩展使用.html.76b3dd90.js" as="script" /><link rel="prefetch" href="/doc/assets/掌握 GIT.html.724416fc.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.8b55f9ef.js" as="script" /><link rel="prefetch" href="/doc/assets/面试题详解.html.8ee968a7.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.06371751.js" as="script" /><link rel="prefetch" href="/doc/assets/面试题详解.html.6b672044.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.b200eaff.js" as="script" /><link rel="prefetch" href="/doc/assets/基础掌握.html.5135d2c4.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.557b7bf5.js" as="script" /><link rel="prefetch" href="/doc/assets/基础掌握.html.7b535b09.js" as="script" /><link rel="prefetch" href="/doc/assets/扩展知识.html.c6b233af.js" as="script" /><link rel="prefetch" href="/doc/assets/项目搭建.html.450f0b1d.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.6483ed06.js" as="script" /><link rel="prefetch" href="/doc/assets/安装及使用.html.b4d859f3.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.f15cf3e9.js" as="script" /><link rel="prefetch" href="/doc/assets/第 1 章.html.127b1e7c.js" as="script" /><link rel="prefetch" href="/doc/assets/第 2 章.html.ea8e67e2.js" as="script" /><link rel="prefetch" href="/doc/assets/Controllers.html.029df1e7.js" as="script" /><link rel="prefetch" href="/doc/assets/Module.html.f102db2a.js" as="script" /><link rel="prefetch" href="/doc/assets/Providers.html.9bef3753.js" as="script" /><link rel="prefetch" href="/doc/assets/404.html.2cfd6b20.js" as="script" /><link rel="prefetch" href="/doc/assets/photoswipe.esm.09e03fed.js" as="script" />
  </head>
  <body>
    <div id="app"><!--[--><!--[--><!--[--><span tabindex="-1"></span><a href="#main-content" class="skip-link sr-only">Skip to content</a><!--]--><div class="theme-container has-toc"><!--[--><!--[--><header class="navbar"><div class="navbar-left"><button class="toggle-sidebar-button" title="Toggle Sidebar"><span class="icon"></span></button><!--[--><!----><!--]--><a href="/doc/" class="brand"><!----><!----><span class="site-name">AT 的文档库</span></a><!--[--><!----><!--]--></div><div class="navbar-center"><!--[--><!----><!--]--><nav class="nav-links"><div class="nav-item hide-in-mobile"><a href="/doc/" class="nav-link" aria-label="首页"><!---->首页<!----></a></div><div class="nav-item hide-in-mobile"><div class="dropdown-wrapper"><button class="dropdown-title" type="button" aria-label="开发问题汇总"><span class="title"><!---->开发问题汇总</span><span class="arrow"></span><ul class="nav-dropdown"><li class="dropdown-item"><a href="/doc/development-question/Vue" class="nav-link" aria-label="Vue"><!---->Vue<!----></a></li></ul></button></div></div><div class="nav-item hide-in-mobile"><div class="dropdown-wrapper"><button class="dropdown-title" type="button" aria-label="系统笔记"><span class="title"><!---->系统笔记</span><span class="arrow"></span><ul class="nav-dropdown"><li class="dropdown-item"><a href="/doc/sysnotes/Git/%E6%8E%8C%E6%8F%A1%20GIT.html" class="nav-link" aria-label="GIT"><!---->GIT<!----></a></li><li class="dropdown-item"><a href="/doc/sysnotes/Nvm/%E5%AE%89%E8%A3%85%E5%8F%8A%E4%BD%BF%E7%94%A8.html" class="nav-link" aria-label="NVM"><!---->NVM<!----></a></li><li class="dropdown-item"><a href="/doc/sysnotes/Linux/%E5%9F%BA%E7%A1%80%E6%8E%8C%E6%8F%A1.html" class="nav-link" aria-label="Linux"><!---->Linux<!----></a></li><li class="dropdown-item"><a href="/doc/sysnotes/JavaScript" class="nav-link" aria-label="JavaScript"><!---->JavaScript<!----></a></li><li class="dropdown-item"><a href="/doc/sysnotes/CSS" class="nav-link" aria-label="CSS"><!---->CSS<!----></a></li><li class="dropdown-item"><a href="/doc/sysnotes/HTML" class="nav-link" aria-label="HTML"><!---->HTML<!----></a></li></ul></button></div></div><div class="nav-item hide-in-mobile"><div class="dropdown-wrapper"><button class="dropdown-title" type="button" aria-label="阅读笔记"><span class="title"><!---->阅读笔记</span><span class="arrow"></span><ul class="nav-dropdown"><li class="dropdown-item"><a href="/doc/readbook/《Vue.js 设计与实现》/" class="nav-link" aria-label="《Vue.js 设计与实现》"><!---->《Vue.js 设计与实现》<!----></a></li><li class="dropdown-item"><a href="/doc/readbook/《TypeScript 编程》/" class="nav-link" aria-label="《TypeScript 编程》"><!---->《TypeScript 编程》<!----></a></li></ul></button></div></div></nav><!--[--><!----><!--]--></div><div class="navbar-right"><!--[--><!----><!--]--><div class="nav-item hide-in-mobile"><button id="appearance-switch"><svg xmlns="http://www.w3.org/2000/svg" class="icon auto-icon" viewBox="0 0 1024 1024" fill="currentColor" aria-label="auto icon" style="display:block;"><path d="M512 992C246.92 992 32 777.08 32 512S246.92 32 512 32s480 214.92 480 480-214.92 480-480 480zm0-840c-198.78 0-360 161.22-360 360 0 198.84 161.22 360 360 360s360-161.16 360-360c0-198.78-161.22-360-360-360zm0 660V212c165.72 0 300 134.34 300 300 0 165.72-134.28 300-300 300z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" class="icon dark-icon" viewBox="0 0 1024 1024" fill="currentColor" aria-label="dark icon" style="display:none;"><path d="M524.8 938.667h-4.267a439.893 439.893 0 0 1-313.173-134.4 446.293 446.293 0 0 1-11.093-597.334A432.213 432.213 0 0 1 366.933 90.027a42.667 42.667 0 0 1 45.227 9.386 42.667 42.667 0 0 1 10.24 42.667 358.4 358.4 0 0 0 82.773 375.893 361.387 361.387 0 0 0 376.747 82.774 42.667 42.667 0 0 1 54.187 55.04 433.493 433.493 0 0 1-99.84 154.88 438.613 438.613 0 0 1-311.467 128z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" class="icon light-icon" viewBox="0 0 1024 1024" fill="currentColor" aria-label="light icon" style="display:none;"><path d="M952 552h-80a40 40 0 0 1 0-80h80a40 40 0 0 1 0 80zM801.88 280.08a41 41 0 0 1-57.96-57.96l57.96-58a41.04 41.04 0 0 1 58 58l-58 57.96zM512 752a240 240 0 1 1 0-480 240 240 0 0 1 0 480zm0-560a40 40 0 0 1-40-40V72a40 40 0 0 1 80 0v80a40 40 0 0 1-40 40zm-289.88 88.08-58-57.96a41.04 41.04 0 0 1 58-58l57.96 58a41 41 0 0 1-57.96 57.96zM192 512a40 40 0 0 1-40 40H72a40 40 0 0 1 0-80h80a40 40 0 0 1 40 40zm30.12 231.92a41 41 0 0 1 57.96 57.96l-57.96 58a41.04 41.04 0 0 1-58-58l58-57.96zM512 832a40 40 0 0 1 40 40v80a40 40 0 0 1-80 0v-80a40 40 0 0 1 40-40zm289.88-88.08 58 57.96a41.04 41.04 0 0 1-58 58l-57.96-58a41 41 0 0 1 57.96-57.96z"></path></svg></button></div><form class="search-box" role="search"><input type="search" autocomplete="off" spellcheck="false" value><!----></form><!--[--><!----><!--]--><button class="toggle-navbar-button" aria-label="Toggle Navbar" aria-expanded="false" aria-controls="nav-screen"><span class="button-container"><span class="button-top"></span><span class="button-middle"></span><span class="button-bottom"></span></span></button></div></header><!----><!--]--><!----><div class="toggle-sidebar-wrapper"><span class="arrow left"></span></div><aside class="sidebar"><!--[--><!----><!--]--><ul class="sidebar-links"><li><section class="sidebar-group"><button class="sidebar-heading clickable active"><!----><span class="title">《TypeScript 编程》</span><span class="arrow down"></span></button><ul class="sidebar-links"><li><!--[--><a href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%201%20%E7%AB%A0%20%E5%AF%BC%E8%A8%80.html" class="nav-link sidebar-link sidebar-page" aria-label="第 1 章 导言"><!---->第 1 章 导言<!----></a><ul class="sidebar-sub-headers"></ul><!--]--></li><li><!--[--><a href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%202%20%E7%AB%A0%20TypeScript%20%E6%A6%82%E8%BF%B0.html" class="nav-link sidebar-link sidebar-page" aria-label="第 2 章 TypeScript 概述"><!---->第 2 章 TypeScript 概述<!----></a><ul class="sidebar-sub-headers"></ul><!--]--></li><li><!--[--><a aria-current="page" href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%203%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E5%85%A8%E8%A7%A3.html" class="router-link-active router-link-exact-active nav-link active sidebar-link sidebar-page active" aria-label="第 3 章 类型全解"><!---->第 3 章 类型全解<!----></a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a aria-current="page" href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%203%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E5%85%A8%E8%A7%A3.html#_3-1-类型术语" class="router-link-active router-link-exact-active nav-link sidebar-link heading" aria-label="3.1 类型术语"><!---->3.1 类型术语<!----></a><ul class="sidebar-sub-headers"></ul></li><li class="sidebar-sub-header"><a aria-current="page" href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%203%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E5%85%A8%E8%A7%A3.html#_3-2-类型浅谈" class="router-link-active router-link-exact-active nav-link sidebar-link heading" aria-label="3.2 类型浅谈"><!---->3.2 类型浅谈<!----></a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a aria-current="page" href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%203%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E5%85%A8%E8%A7%A3.html#_3-2-1-any" class="router-link-active router-link-exact-active nav-link sidebar-link heading" aria-label="3.2.1 any"><!---->3.2.1 any<!----></a><ul class="sidebar-sub-headers"></ul></li><li class="sidebar-sub-header"><a aria-current="page" href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%203%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E5%85%A8%E8%A7%A3.html#_3-2-2-unknown" class="router-link-active router-link-exact-active nav-link sidebar-link heading" aria-label="3.2.2 unknown"><!---->3.2.2 unknown<!----></a><ul class="sidebar-sub-headers"></ul></li><li class="sidebar-sub-header"><a aria-current="page" href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%203%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E5%85%A8%E8%A7%A3.html#_3-2-3-boolean" class="router-link-active router-link-exact-active nav-link sidebar-link heading" aria-label="3.2.3 boolean"><!---->3.2.3 boolean<!----></a><ul class="sidebar-sub-headers"></ul></li><li class="sidebar-sub-header"><a aria-current="page" href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%203%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E5%85%A8%E8%A7%A3.html#_3-2-4-number" class="router-link-active router-link-exact-active nav-link sidebar-link heading" aria-label="3.2.4 number"><!---->3.2.4 number<!----></a><ul class="sidebar-sub-headers"></ul></li><li class="sidebar-sub-header"><a aria-current="page" href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%203%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E5%85%A8%E8%A7%A3.html#_3-2-5-bigint" class="router-link-active router-link-exact-active nav-link sidebar-link heading" aria-label="3.2.5 bigint"><!---->3.2.5 bigint<!----></a><ul class="sidebar-sub-headers"></ul></li><li class="sidebar-sub-header"><a aria-current="page" href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%203%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E5%85%A8%E8%A7%A3.html#_3-2-6-string" class="router-link-active router-link-exact-active nav-link sidebar-link heading" aria-label="3.2.6 string"><!---->3.2.6 string<!----></a><ul class="sidebar-sub-headers"></ul></li><li class="sidebar-sub-header"><a aria-current="page" href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%203%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E5%85%A8%E8%A7%A3.html#_3-2-7-symbol" class="router-link-active router-link-exact-active nav-link sidebar-link heading" aria-label="3.2.7 symbol"><!---->3.2.7 symbol<!----></a><ul class="sidebar-sub-headers"></ul></li><li class="sidebar-sub-header"><a aria-current="page" href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%203%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E5%85%A8%E8%A7%A3.html#_3-2-8-对象" class="router-link-active router-link-exact-active nav-link sidebar-link heading" aria-label="3.2.8 对象"><!---->3.2.8 对象<!----></a><ul class="sidebar-sub-headers"></ul></li><li class="sidebar-sub-header"><a aria-current="page" href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%203%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E5%85%A8%E8%A7%A3.html#_3-2-9-类型别名、并集和交集" class="router-link-active router-link-exact-active nav-link sidebar-link heading" aria-label="3.2.9 类型别名、并集和交集"><!---->3.2.9 类型别名、并集和交集<!----></a><ul class="sidebar-sub-headers"></ul></li><li class="sidebar-sub-header"><a aria-current="page" href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%203%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E5%85%A8%E8%A7%A3.html#_3-2-10-数组" class="router-link-active router-link-exact-active nav-link sidebar-link heading" aria-label="3.2.10 数组"><!---->3.2.10 数组<!----></a><ul class="sidebar-sub-headers"></ul></li><li class="sidebar-sub-header"><a aria-current="page" href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%203%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E5%85%A8%E8%A7%A3.html#_3-2-11-元组" class="router-link-active router-link-exact-active nav-link sidebar-link heading" aria-label="3.2.11 元组"><!---->3.2.11 元组<!----></a><ul class="sidebar-sub-headers"></ul></li><li class="sidebar-sub-header"><a aria-current="page" href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%203%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E5%85%A8%E8%A7%A3.html#_3-2-12-null、undefined、void-和-never" class="router-link-active router-link-exact-active nav-link sidebar-link heading" aria-label="3.2.12 null、undefined、void 和 never"><!---->3.2.12 null、undefined、void 和 never<!----></a><ul class="sidebar-sub-headers"></ul></li><li class="sidebar-sub-header"><a aria-current="page" href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%203%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E5%85%A8%E8%A7%A3.html#_3-2-13-枚举" class="router-link-active router-link-exact-active nav-link sidebar-link heading" aria-label="3.2.13 枚举"><!---->3.2.13 枚举<!----></a><ul class="sidebar-sub-headers"></ul></li></ul></li><li class="sidebar-sub-header"><a aria-current="page" href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%203%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E5%85%A8%E8%A7%A3.html#_3-3-小结" class="router-link-active router-link-exact-active nav-link sidebar-link heading" aria-label="3.3 小结"><!---->3.3 小结<!----></a><ul class="sidebar-sub-headers"></ul></li></ul><!--]--></li><li><!--[--><a href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%204%20%E7%AB%A0%20%E5%87%BD%E6%95%B0.html" class="nav-link sidebar-link sidebar-page" aria-label="第 4 章 函数"><!---->第 4 章 函数<!----></a><ul class="sidebar-sub-headers"></ul><!--]--></li><li><!--[--><a href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%205%20%E7%AB%A0%20%E7%B1%BB%E5%92%8C%E6%8E%A5%E5%8F%A3.html" class="nav-link sidebar-link sidebar-page" aria-label="第 5 章 类和接口"><!---->第 5 章 类和接口<!----></a><ul class="sidebar-sub-headers"></ul><!--]--></li><li><!--[--><a href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%206%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E8%BF%9B%E9%98%B6.html" class="nav-link sidebar-link sidebar-page" aria-label="第 6 章 类型进阶"><!---->第 6 章 类型进阶<!----></a><ul class="sidebar-sub-headers"></ul><!--]--></li></ul></section></li><li><section class="sidebar-group"><button class="sidebar-heading clickable"><!----><span class="title">《Vue.js 设计与实现》</span><span class="arrow right"></span></button><!----></section></li></ul><!--[--><!----><!--]--></aside><!--[--><main class="page" id="main-content"><!--[--><!----><nav class="breadcrumb disable"></nav><div class="page-title"><h1><!---->第 3 章 类型全解</h1><div class="page-info"><!----><!----><!----><!----><!----><span class="reading-time-info" aria-label="阅读时间⌛" data-balloon-pos="down"><svg xmlns="http://www.w3.org/2000/svg" class="icon timer-icon" viewBox="0 0 1024 1024" fill="currentColor" aria-label="timer icon"><path d="M799.387 122.15c4.402-2.978 7.38-7.897 7.38-13.463v-1.165c0-8.933-7.38-16.312-16.312-16.312H256.33c-8.933 0-16.311 7.38-16.311 16.312v1.165c0 5.825 2.977 10.874 7.637 13.592 4.143 194.44 97.22 354.963 220.201 392.763-122.204 37.542-214.893 196.511-220.2 389.397-4.661 5.049-7.638 11.651-7.638 19.03v5.825h566.49v-5.825c0-7.379-2.849-13.981-7.509-18.9-5.049-193.016-97.867-351.985-220.2-389.527 123.24-37.67 216.446-198.453 220.588-392.892zM531.16 450.445v352.632c117.674 1.553 211.787 40.778 211.787 88.676H304.097c0-48.286 95.149-87.382 213.728-88.676V450.445c-93.077-3.107-167.901-81.297-167.901-177.093 0-8.803 6.99-15.793 15.793-15.793 8.803 0 15.794 6.99 15.794 15.793 0 80.261 63.69 145.635 142.01 145.635s142.011-65.374 142.011-145.635c0-8.803 6.99-15.793 15.794-15.793s15.793 6.99 15.793 15.793c0 95.019-73.789 172.82-165.96 177.093z"></path></svg><span>大约 13 分钟</span><meta property="timeRequired" content="PT13M"></span></div><hr></div><div class="toc-place-holder"><aside id="toc"><div class="toc-header">此页内容</div><div class="toc-wrapper"><ul class="toc-list"><!--[--><li class="toc-item"><a aria-current="page" href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%203%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E5%85%A8%E8%A7%A3.html#_3-1-类型术语" class="router-link-active router-link-exact-active toc-link level2">3.1 类型术语</a></li><!----><!--]--><!--[--><li class="toc-item"><a aria-current="page" href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%203%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E5%85%A8%E8%A7%A3.html#_3-2-类型浅谈" class="router-link-active router-link-exact-active toc-link level2">3.2 类型浅谈</a></li><ul class="toc-list"><!--[--><li class="toc-item"><a aria-current="page" href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%203%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E5%85%A8%E8%A7%A3.html#_3-2-1-any" class="router-link-active router-link-exact-active toc-link level3">3.2.1 any</a></li><!----><!--]--><!--[--><li class="toc-item"><a aria-current="page" href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%203%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E5%85%A8%E8%A7%A3.html#_3-2-2-unknown" class="router-link-active router-link-exact-active toc-link level3">3.2.2 unknown</a></li><!----><!--]--><!--[--><li class="toc-item"><a aria-current="page" href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%203%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E5%85%A8%E8%A7%A3.html#_3-2-3-boolean" class="router-link-active router-link-exact-active toc-link level3">3.2.3 boolean</a></li><!----><!--]--><!--[--><li class="toc-item"><a aria-current="page" href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%203%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E5%85%A8%E8%A7%A3.html#_3-2-4-number" class="router-link-active router-link-exact-active toc-link level3">3.2.4 number</a></li><!----><!--]--><!--[--><li class="toc-item"><a aria-current="page" href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%203%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E5%85%A8%E8%A7%A3.html#_3-2-5-bigint" class="router-link-active router-link-exact-active toc-link level3">3.2.5 bigint</a></li><!----><!--]--><!--[--><li class="toc-item"><a aria-current="page" href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%203%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E5%85%A8%E8%A7%A3.html#_3-2-6-string" class="router-link-active router-link-exact-active toc-link level3">3.2.6 string</a></li><!----><!--]--><!--[--><li class="toc-item"><a aria-current="page" href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%203%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E5%85%A8%E8%A7%A3.html#_3-2-7-symbol" class="router-link-active router-link-exact-active toc-link level3">3.2.7 symbol</a></li><!----><!--]--><!--[--><li class="toc-item"><a aria-current="page" href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%203%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E5%85%A8%E8%A7%A3.html#_3-2-8-对象" class="router-link-active router-link-exact-active toc-link level3">3.2.8 对象</a></li><!----><!--]--><!--[--><li class="toc-item"><a aria-current="page" href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%203%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E5%85%A8%E8%A7%A3.html#_3-2-9-类型别名、并集和交集" class="router-link-active router-link-exact-active toc-link level3">3.2.9 类型别名、并集和交集</a></li><!----><!--]--><!--[--><li class="toc-item"><a aria-current="page" href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%203%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E5%85%A8%E8%A7%A3.html#_3-2-10-数组" class="router-link-active router-link-exact-active toc-link level3">3.2.10 数组</a></li><!----><!--]--><!--[--><li class="toc-item"><a aria-current="page" href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%203%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E5%85%A8%E8%A7%A3.html#_3-2-11-元组" class="router-link-active router-link-exact-active toc-link level3">3.2.11 元组</a></li><!----><!--]--><!--[--><li class="toc-item"><a aria-current="page" href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%203%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E5%85%A8%E8%A7%A3.html#_3-2-12-null、undefined、void-和-never" class="router-link-active router-link-exact-active toc-link level3">3.2.12 null、undefined、void 和 never</a></li><!----><!--]--><!--[--><li class="toc-item"><a aria-current="page" href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%203%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E5%85%A8%E8%A7%A3.html#_3-2-13-枚举" class="router-link-active router-link-exact-active toc-link level3">3.2.13 枚举</a></li><!----><!--]--></ul><!--]--><!--[--><li class="toc-item"><a aria-current="page" href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%203%20%E7%AB%A0%20%E7%B1%BB%E5%9E%8B%E5%85%A8%E8%A7%A3.html#_3-3-小结" class="router-link-active router-link-exact-active toc-link level2">3.3 小结</a></li><!----><!--]--></ul></div></aside></div><!----><div class="theme-hope-content"><h1 id="第-3-章-类型全解" tabindex="-1"><a class="header-anchor" href="#第-3-章-类型全解" aria-hidden="true">#</a> 第 3 章 类型全解</h1><blockquote><p>类型：一系列值及可以对其执行的操作。</p></blockquote><p>举个🌰：</p><ul><li>boolean 类型包含所有的布尔值（true 和 false），以及可以对布尔值执行的操作（||、**、！）等。</li><li>number 类型包括所有数字，以及可以对数字执行的操作（+、-、*、/、&amp;、||、&amp;&amp; 和 ?）,还可以在数字上调用的方法，如：.toFixed、.toPrecision、.toString 等。</li><li>string 类型包括所有字符串，以及可以对字符串执行的操作（+、||、&amp;&amp;），还有可以在字符穿上调用的方法，如：.concat、.toUpperCase</li></ul><p>对 T 类型的值来说，不仅知道类型是 T，还知道可以（及不可以）对该值做什么操作。最终是由类型检查器阻止做无效的操作。而类型检查器则通过使用类型和具体用法判操作是否有效。</p><p>TypeScript 的类型层次结构如下：</p><p><img src="/doc/assets/3.1.7c788bd7.png" alt="TypeScript 的类型层次结构"></p><h2 id="_3-1-类型术语" tabindex="-1"><a class="header-anchor" href="#_3-1-类型术语" aria-hidden="true">#</a> 3.1 类型术语</h2><p>可以把类型注解看作为某种界限。</p><p>本小节没有过多内容不做笔记。</p><h2 id="_3-2-类型浅谈" tabindex="-1"><a class="header-anchor" href="#_3-2-类型浅谈" aria-hidden="true">#</a> 3.2 类型浅谈</h2><p>此小节逐一介绍 TypeScript 支持类型、各类型包含的值，以及可以对类型执行的操作。还包含一些类型有关的基本与延特性：类型别名、并集类型和交集类型</p><h3 id="_3-2-1-any" tabindex="-1"><a class="header-anchor" href="#_3-2-1-any" aria-hidden="true">#</a> 3.2.1 any</h3><p>any 是类型的“教父”。在 TypeScript 中，编译时一切都要有类型，如果开发者和类型检查器无法确定类型，则默认为 any。是兜底类型，尽量避免使用。</p><p>any 类型包含所有值，而且可以对其做任何操作。any 类型的值就像常规的 JS 一样，类型检查器完全没有作用。</p><div class="custom-container tip"><p class="custom-container-title">TSC 标志：noImplicitAny</p><p>默认情况下，TypeScript 很宽容，在推导出类型为 any 时不会报错。如果想让 TypeScript 在遇到隐式 any 类型时报错，需要在 tsconfig.json 中启用 noImplicitAny 标志。</p><p>noImplicitAny 隶属于 TSC 的 strict。如果已经在 tsconfig.json 中启用 strict 就不需要单独设置。</p></div><h3 id="_3-2-2-unknown" tabindex="-1"><a class="header-anchor" href="#_3-2-2-unknown" aria-hidden="true">#</a> 3.2.2 unknown</h3><p>如果确定无法预知一个值的类型，不要使用 any，应该使用 unkonwn。与 any 类似，unknown 也表示任何值，但是 TypeScript 会要求再做检查，细化类型。</p><p>unknown 类型支持操作：比较（==、===、||、&amp;&amp; 和 ？）、否定（!）、可以使用 JavasScript 和 typeof 和 instanceof 运算符细化。</p><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token keyword">let</span> a<span class="token operator">:</span> <span class="token builtin">unknown</span> <span class="token operator">=</span> <span class="token number">30</span><span class="token punctuation">;</span> <span class="token comment">// unknown</span>

<span class="token keyword">let</span> b <span class="token operator">=</span> a <span class="token operator">===</span> <span class="token number">123</span><span class="token punctuation">;</span> <span class="token comment">// boolean</span>

<span class="token keyword">let</span> c <span class="token operator">=</span> a <span class="token operator">+</span> <span class="token number">10</span><span class="token punctuation">;</span> <span class="token comment">// Error TS2571:Object is of type &#39;unknown&#39;</span>

</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><ol><li>TypeScript 不会把任何值推导为 unknown 类型，必须显示注解。</li><li>unknown 类型的值可以比较</li><li>在执行操作室，不能假定 unknown 类型值为某种特定类型。必须先向 TypeScript 声明类型。</li></ol><div class="custom-container tip"><p class="custom-container-title">提示</p><p>如果 unknown 是并集类型的一部分，联合的结果是 unknown。并集类型的详细说明间<a href="#_3-2-9-%E7%B1%BB%E5%9E%8B%E5%88%AB%E5%90%8D%E3%80%81%E5%B9%B6%E9%9B%86%E5%92%8C%E4%BA%A4%E9%9B%86">并集类型和交集类型</a></p></div><h3 id="_3-2-3-boolean" tabindex="-1"><a class="header-anchor" href="#_3-2-3-boolean" aria-hidden="true">#</a> 3.2.3 boolean</h3><p>boolean 类型有两个值：true 和 false。该类型的值可以比较（==、===、||、&amp;&amp; 和 ?）、否定（!）。</p><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span>                   <span class="token comment">// boolean</span>
<span class="token keyword">let</span> b <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span>                   <span class="token comment">// boolean</span>
<span class="token keyword">let</span> c<span class="token operator">:</span> <span class="token builtin">boolean</span> <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span>         <span class="token comment">// boolean</span>
<span class="token keyword">let</span> d<span class="token operator">:</span> <span class="token builtin">boolean</span> <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span>          <span class="token comment">// boolean</span>
<span class="token keyword">let</span> e<span class="token operator">:</span> <span class="token boolean">true</span> <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span>             <span class="token comment">// true</span>
<span class="token keyword">let</span> f<span class="token operator">:</span> <span class="token boolean">false</span> <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span>            <span class="token comment">// Error TS 2322:Type &#39;false&#39; is not assignable to type &#39;true&#39;</span>
<span class="token keyword">const</span> g <span class="token operator">=</span> <span class="token boolean">true</span>                  <span class="token comment">// true</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><ol><li>TypeScript 可以推导出 a 和 b 的类型为 boolean</li><li>TypeScript 可以推导出常量 g 的具体类型值</li><li>可以声明类型</li><li>可以明确某个变量的值</li></ol><blockquote><p>类型字面量：仅表示一个值的类型，如上述：<code>let e:true = true</code></p></blockquote><p>const 生命的基本类型值，赋值后便无法修改，因此 TypeScript 推导出的是最窄的类型。</p><p>类型字面量，能让安全性更上一层楼。</p><h3 id="_3-2-4-number" tabindex="-1"><a class="header-anchor" href="#_3-2-4-number" aria-hidden="true">#</a> 3.2.4 number</h3><p>number 包含：整数、浮点数、正数、负数、Infinity、NaN 等。</p><ol><li>自动推导类型</li><li>使用 const 推导类型为某个值</li><li>声明类型</li><li>声明类型为具体值</li></ol><p>没有特殊原因，不推荐把值得类型显示注解为 number</p><div class="custom-container tip"><p class="custom-container-title">提示</p><p>处理较长的数字时，为了辨识数字，建议使用数字分隔符。类型和值所在位置上均可使用。</p><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token keyword">let</span> oneMillion  <span class="token operator">=</span> <span class="token number">1_000_000</span> <span class="token comment">// 等同于 1000000</span>
<span class="token keyword">let</span> twoMillion<span class="token operator">:</span><span class="token number">2_000_000</span> <span class="token operator">=</span> <span class="token number">2_000_000</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div></div></div></div><h3 id="_3-2-5-bigint" tabindex="-1"><a class="header-anchor" href="#_3-2-5-bigint" aria-hidden="true">#</a> 3.2.5 bigint</h3><p>bigIng 是 JavaScript 和 TypeScript 新引入的类型，在处理较大的整数时，不用再担心舍入误差。 number 类型表示的最大为 2<sup>53</sup>，bigint 能表示的比这大很多。bigint 类型包含所有 BigInt 数。</p><p>使用方式同 boolean 和 number。尽量让 TypeScript 推导 bigint 类型。</p><h3 id="_3-2-6-string" tabindex="-1"><a class="header-anchor" href="#_3-2-6-string" aria-hidden="true">#</a> 3.2.6 string</h3><p>string 包含所有字符串，以及可以对字符串执行的操作。具有与 boolean 和 number 一样的声明方式。尽量让 TypeScript 推导 string 类型。</p><h3 id="_3-2-7-symbol" tabindex="-1"><a class="header-anchor" href="#_3-2-7-symbol" aria-hidden="true">#</a> 3.2.7 symbol</h3><p>symbol 是 ES6 新推出类型。用于代替对象和映射的字符串键，确保使用正确的已知键，以防减被意外设置。例如设置对象的默认迭代器（Symbol.iterator）,或者在运行时覆盖不管对象是什么的实例（Symbol.hasInstance）。</p><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">&quot;a&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> b<span class="token operator">:</span> <span class="token builtin">symbol</span> <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">&quot;b&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">var</span> c <span class="token operator">=</span> a <span class="token operator">===</span> b<span class="token punctuation">;</span>

<span class="token keyword">let</span> d <span class="token operator">=</span> a <span class="token operator">+</span> <span class="token string">&quot;x&quot;</span><span class="token punctuation">;</span> <span class="token comment">//Error: &quot;+&quot; 运算符不能用于类型 &quot;symbol&quot;</span>

</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>除与 number 相同的声明类型方式外，还可以显示的声明 unique symbol 类型:</p><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token keyword">const</span> e <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">&quot;e&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> f<span class="token operator">:</span> unique <span class="token builtin">symbol</span> <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">&quot;f&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> g<span class="token operator">:</span> unique <span class="token builtin">symbol</span> <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">&quot;f&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Errro：类型为 unique symbol 的变量必须为 const</span>

<span class="token keyword">let</span> h <span class="token operator">=</span> e <span class="token operator">===</span> e<span class="token punctuation">;</span>
<span class="token keyword">let</span> i <span class="token operator">=</span> e <span class="token operator">===</span> f<span class="token punctuation">;</span> <span class="token comment">// 此条件将使用返回 “false”,因为类型 typeof e 和 typeof f 没有重叠</span>

</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><ol><li>使用 const 声名的符号，TypeSript 推导为 unique symbol 类型。在编辑器中显示为 typeof variableName，而不是 unique symbol。</li><li>可显示注解 const 变量的类型为 unique symbol。</li><li>unique symbol 类型的值始终与自身相等。</li><li>两个 unique symbol 类型的值永远不会相等。</li></ol><h3 id="_3-2-8-对象" tabindex="-1"><a class="header-anchor" href="#_3-2-8-对象" aria-hidden="true">#</a> 3.2.8 对象</h3><p>通过对象类型无法区分不同的简单对象（使用{}创建）或复杂对象（使用 new Blah 创建）。JavaScript 采用结构化类型。</p><blockquote><p>结构化类型：一种编程设计风格，只关心对象有哪些属性，而不管属性使用什么名称（名义化类型）。在某些程序语言中也成为鸭子类型。</p></blockquote><p>使用类型描述对象：</p><ol><li><p>把值声明成 object 类型 <code>let o: object = { a: 123 }</code>，此时访问 <code>o.a</code> 时，TypeScript 会提示错误： Property &#39;a&#39; does not exist no type &#39;object&#39;，因为此种方式只是表示 o 为一个对象，但是对象上是否存在 a 的属性是未知的。</p></li><li><p>使用对象字面量声明对象，可以让 TypeScript 自动推导对象结构。</p></li></ol><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token keyword">let</span> o <span class="token operator">=</span> <span class="token punctuation">{</span>
    a<span class="token operator">:</span><span class="token number">1</span>
<span class="token punctuation">}</span>

<span class="token keyword">let</span> o<span class="token operator">:</span><span class="token punctuation">{</span>
    a<span class="token operator">:</span><span class="token builtin">number</span>
<span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">{</span>
    a<span class="token operator">:</span><span class="token number">1</span>
<span class="token punctuation">}</span>

</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote><p>使用 const 声明对象时的类型推导：<code>const o:{a:number} = {a:12}</code></p><p>TypeScript 推导出的 a 类型是 number，而不是字面量 12。前边说 number 和 string 时，使用 const 声明变量，TypeScript 推导出类型是字面量。 而对象则不会导师 TypeScript 把推导的类型缩窄。因为 JavaScript 的对象是可变的。</p></blockquote><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token keyword">let</span> o<span class="token operator">:</span><span class="token punctuation">{</span>
    a<span class="token operator">:</span><span class="token builtin">number</span><span class="token punctuation">,</span>
    b<span class="token operator">?</span><span class="token operator">:</span><span class="token builtin">string</span><span class="token punctuation">,</span>
    <span class="token punctuation">[</span>key<span class="token operator">:</span><span class="token builtin">number</span><span class="token punctuation">]</span><span class="token operator">:</span><span class="token builtin">boolean</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><ol><li>对象 o 有个类型为 number 的属性 a</li><li>类型为 string 的可选属性 b</li><li>可能有任意多个 number 属性，值为 boolean</li></ol><div class="custom-container tip"><p class="custom-container-title">索引签名</p><p>[key:T]:U 句法称为索引签名，通过该方式通知 TypeScript 指定的对象可能有多个建。</p><p>[key:T]:U 解析为：在当前对象中，类型为 T 的键对应的值为 U。</p><p>借助索引签名，除显示声明的键之外，可以放心添加更多的键。</p><p>索引签名键的类型（T）必须可赋值给 number 或 string。另外，key 可以是任意词。</p></div><p>声明对象类型时，可选符号（?）不是唯一可用的修饰符。还可以使用 readonly 修饰符把字段标记为只读。</p><p>对象字面量表示法有个特例：空对象类型（{}）。除 null 和 undefined 之外的任何类型都可以赋值给空对象类型。应尽量避免使用。</p><p>综上，TypeScript 声明对象类型有四种方式：</p><ol><li>对象字面量表示法，也称对象的结构。如果知道对象有哪些字段，或者对象的值都为相同的类型，可以使用这种方式。</li><li>空对象字面量表示法。尽量避免。</li><li>object 类型，如果需要一个对象，但是对象的字段没有要求，可以使用该方法。</li><li>Object 类型。尽量避免。</li></ol><p>值是否有效可参考下表：</p><table><thead><tr><th>值</th><th>{}</th><th>object</th><th>Object</th></tr></thead><tbody><tr><td>{}</td><td>Y</td><td>Y</td><td>Y</td></tr><tr><td>[&#39;a&#39;]</td><td>Y</td><td>Y</td><td>Y</td></tr><tr><td>fuction(){}</td><td>Y</td><td>Y</td><td>Y</td></tr><tr><td>new String(&#39;123&#39;)</td><td>Y</td><td>Y</td><td>Y</td></tr><tr><td>&#39;a&#39;</td><td>Y</td><td><strong>N</strong></td><td>Y</td></tr><tr><td>1</td><td>Y</td><td><strong>N</strong></td><td>Y</td></tr><tr><td>Symbol(&#39;a&#39;)</td><td>Y</td><td><strong>N</strong></td><td>Y</td></tr><tr><td>null</td><td><strong>N</strong></td><td><strong>N</strong></td><td><strong>N</strong></td></tr><tr><td>undefined</td><td><strong>N</strong></td><td><strong>N</strong></td><td><strong>N</strong></td></tr></tbody></table><h3 id="_3-2-9-类型别名、并集和交集" tabindex="-1"><a class="header-anchor" href="#_3-2-9-类型别名、并集和交集" aria-hidden="true">#</a> 3.2.9 类型别名、并集和交集</h3><h4 id="类型别名" tabindex="-1"><a class="header-anchor" href="#类型别名" aria-hidden="true">#</a> 类型别名</h4><p>可以使用 let、const 和 var 声明变量。类型也可以类似的声明别名。</p><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token comment">// 定义类型</span>
<span class="token keyword">type</span> <span class="token class-name">Age</span> <span class="token operator">=</span> <span class="token builtin">number</span>
<span class="token keyword">type</span> <span class="token class-name">Person</span> <span class="token operator">=</span> <span class="token punctuation">{</span>
    name<span class="token operator">:</span><span class="token builtin">string</span>
    age<span class="token operator">:</span>Age
<span class="token punctuation">}</span>

<span class="token comment">// 使用</span>
<span class="token keyword">let</span> age<span class="token operator">:</span>Age <span class="token operator">=</span> <span class="token number">18</span>
<span class="token keyword">let</span> at<span class="token operator">:</span>Person <span class="token operator">=</span> <span class="token punctuation">{</span>
    name<span class="token operator">:</span><span class="token string">&#39;at&#39;</span><span class="token punctuation">,</span>
    age<span class="token operator">:</span>age
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>与 JavaScript 中的变量声明(let、const) 一样，同一类型不能生命两次。 同样与 let 和 const 一样的是，类型别名采用块级作用域。每一块代码和每一个函数都有自己的作用域，内部的类型别名将覆盖外部的类型别名。</p><p>类型别名有助于减少重复输入复杂的类型（DRY），还能更清楚地表明变量的作用。</p><div class="custom-container tip"><p class="custom-container-title">DRY</p><p>DRY 是 “Don&#39;t Repeat Yourself” 首字母缩写，意思是不要重复编写代码。</p></div><h4 id="并集类型和交集类型" tabindex="-1"><a class="header-anchor" href="#并集类型和交集类型" aria-hidden="true">#</a> 并集类型和交集类型</h4><img decoding="async" alt="并集、交集" src="/doc/assets/bingji_jiaoji.03f8c0df.png" width="50%" style="display:block;margin:0 auto;"><p>如图：A+B+C = 并集（|）、C = 交集（&amp;）</p><p>TypeScript 提供特殊的类型运算符：并集（|）和交集（&amp;）。</p><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token keyword">type</span> <span class="token class-name">Cat</span> <span class="token operator">=</span> <span class="token punctuation">{</span>name<span class="token operator">:</span><span class="token builtin">string</span><span class="token punctuation">,</span>age<span class="token operator">:</span><span class="token builtin">number</span><span class="token punctuation">}</span>
<span class="token keyword">type</span> <span class="token class-name">Dog</span> <span class="token operator">=</span> <span class="token punctuation">{</span>name<span class="token operator">:</span><span class="token builtin">string</span><span class="token punctuation">,</span>wags<span class="token operator">:</span><span class="token builtin">boolean</span><span class="token punctuation">}</span>

<span class="token keyword">type</span> <span class="token class-name">Both</span> <span class="token operator">=</span> Cat <span class="token operator">|</span> Dog
<span class="token keyword">type</span> <span class="token class-name">And</span>  <span class="token operator">=</span> Cat <span class="token operator">&amp;</span> Dog
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="_3-2-10-数组" tabindex="-1"><a class="header-anchor" href="#_3-2-10-数组" aria-hidden="true">#</a> 3.2.10 数组</h3><p>举🌰：</p><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">]</span>             <span class="token comment">// number[]</span>
<span class="token keyword">var</span> b <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">&#39;a&#39;</span><span class="token punctuation">,</span><span class="token string">&#39;b&#39;</span><span class="token punctuation">]</span>           <span class="token comment">// string[]</span>
<span class="token keyword">let</span> c<span class="token operator">:</span><span class="token builtin">string</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">&#39;a&#39;</span><span class="token punctuation">]</span>      <span class="token comment">// string[]</span>
<span class="token keyword">let</span> d <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token string">&#39;a&#39;</span><span class="token punctuation">]</span>             <span class="token comment">// (string|number)[]</span>
<span class="token keyword">const</span> e <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token string">&#39;b&#39;</span><span class="token punctuation">]</span>           <span class="token comment">// (string|number)[]</span>

<span class="token keyword">let</span> f <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">&#39;red&#39;</span><span class="token punctuation">]</span>             <span class="token comment">// string[]</span>
f<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token string">&#39;blue&#39;</span><span class="token punctuation">)</span>
f<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span>                   <span class="token comment">// Error:类型 number 不能赋值给类型 string 的值</span>

</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container tip"><p class="custom-container-title">提示</p><p>TypeScript 支持两种注解数组的方式：T[] 和 Array&lt;T&gt;。两者性能无差别。</p></div><p>初始化空数组是，TypeScript 不知道数组中的元素类型，推导出的类型为 any。向数组中添加元素后 TypeSript 开始拼凑数组的类型。 当数组离开定义时所在的作用于后，TypeScript 将最终确定一个类型，不再扩张。</p><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token keyword">function</span> <span class="token function">buildArray</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
 <span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
 arr<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span>        <span class="token comment">// number[]</span>
 arr<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token string">&#39;a&#39;</span><span class="token punctuation">)</span>      <span class="token comment">// (string|number)[]</span>

 <span class="token keyword">return</span> arr
<span class="token punctuation">}</span>

<span class="token keyword">let</span> _arr <span class="token operator">=</span> <span class="token function">buildArray</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// (string|number)[]</span>

_arr<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token comment">// Error:Argument of the &#39;true&#39; is not assignable to parameter of type &#39;string|number&#39;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="_3-2-11-元组" tabindex="-1"><a class="header-anchor" href="#_3-2-11-元组" aria-hidden="true">#</a> 3.2.11 元组</h3><p>元组是 array 的子类型，是定义数组的一种特殊方式，长度固定，个索引上的值具有固定的已知类型。 与其他多数类型不同，声明元组是必须显示注解类型。因为创建元组使用的句法与数组相同。而 TypeScript 遇到 [] 推导出的类型是数组。</p><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token keyword">let</span> a<span class="token operator">:</span><span class="token punctuation">[</span><span class="token builtin">number</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span>
<span class="token keyword">let</span> b<span class="token operator">:</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">,</span><span class="token builtin">string</span><span class="token punctuation">,</span><span class="token builtin">number</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">&#39;a&#39;</span><span class="token punctuation">,</span><span class="token string">&#39;b&#39;</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">]</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div></div></div><p>元组也支持可选元素。域对象中一样 ? 表示可选。</p><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token keyword">let</span> a<span class="token operator">:</span><span class="token punctuation">[</span><span class="token builtin">number</span><span class="token punctuation">,</span><span class="token builtin">number</span><span class="token operator">?</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token operator">=</span><span class="token punctuation">[</span>
    <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span>
<span class="token punctuation">]</span>
<span class="token comment">// 等价于</span>
<span class="token keyword">let</span> a<span class="token operator">:</span><span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token builtin">number</span><span class="token punctuation">]</span><span class="token operator">|</span><span class="token punctuation">[</span><span class="token builtin">number</span><span class="token punctuation">,</span><span class="token builtin">number</span><span class="token punctuation">]</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>元组也支持剩余元素，即为元组定义最小长度：</p><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token comment">// 字符串数组，最少有一个元素</span>
<span class="token keyword">let</span> a<span class="token operator">:</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">,</span><span class="token operator">...</span><span class="token builtin">string</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">&#39;a&#39;</span><span class="token punctuation">]</span>

<span class="token comment">// 元素类型不同的列表</span>
<span class="token keyword">let</span> b<span class="token operator">:</span><span class="token punctuation">[</span><span class="token builtin">number</span><span class="token punctuation">,</span><span class="token builtin">boolean</span><span class="token punctuation">,</span><span class="token operator">...</span><span class="token builtin">string</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token boolean">false</span><span class="token punctuation">,</span><span class="token string">&#39;a&#39;</span><span class="token punctuation">,</span><span class="token string">&#39;b&#39;</span><span class="token punctuation">,</span><span class="token string">&#39;c&#39;</span><span class="token punctuation">]</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>元组类型能正确定义元素类型不同的列表，还能知晓该列表的长度。这些特性使元组比数组安全得多，应经常使用。</p><h4 id="只读数组和元组" tabindex="-1"><a class="header-anchor" href="#只读数组和元组" aria-hidden="true">#</a> 只读数组和元组</h4><p>TypeScript 原生支持只读数组类型，用于创建不能改变的数组。若想更改使用非变型方法：.concat 和 .slice</p><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token keyword">let</span> arr<span class="token operator">:</span><span class="token keyword">readonly</span> nunmber<span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">]</span>

<span class="token keyword">type</span> <span class="token class-name"><span class="token constant">A</span></span> <span class="token operator">=</span> <span class="token keyword">readonly</span> <span class="token builtin">string</span><span class="token punctuation">[</span><span class="token punctuation">]</span>
<span class="token keyword">type</span> <span class="token class-name"><span class="token constant">B</span></span> <span class="token operator">=</span> ReadonlyArray<span class="token operator">&lt;</span><span class="token builtin">string</span><span class="token operator">&gt;</span>
<span class="token keyword">type</span> <span class="token class-name"><span class="token constant">C</span></span> <span class="token operator">=</span> Readonly<span class="token operator">&lt;</span><span class="token builtin">string</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token operator">&gt;</span>

<span class="token keyword">type</span> <span class="token class-name"><span class="token constant">D</span></span> <span class="token operator">=</span> <span class="token keyword">readonly</span> <span class="token punctuation">[</span><span class="token builtin">number</span><span class="token punctuation">,</span><span class="token builtin">string</span><span class="token punctuation">]</span>
<span class="token keyword">type</span> <span class="token class-name"><span class="token constant">E</span></span> <span class="token operator">=</span> Readonly<span class="token operator">&lt;</span><span class="token punctuation">[</span><span class="token builtin">number</span><span class="token punctuation">,</span><span class="token builtin">string</span><span class="token punctuation">]</span><span class="token operator">&gt;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="_3-2-12-null、undefined、void-和-never" tabindex="-1"><a class="header-anchor" href="#_3-2-12-null、undefined、void-和-never" aria-hidden="true">#</a> 3.2.12 null、undefined、void 和 never</h3><p>在 TypeScript 中，undefined 类型只有一个 undefined 值。null 类型只有一个 null 值。</p><p>undefined 的意思是尚未定义，而 null 表示缺少值。</p><p>除 null 和 undefined 之外，TypeScript 还有 void 和 never 类型。这两个类型哟偶明确的特殊作用，进一步划分不同情况下的“不存在”： void 势函数没有显示返回任何值时的返回类型，而 never 是函数根本不返回时（例如函数抛出异常，或者永远执行下去）使用的类型。</p><p>如果 unknown 是其他类型的父类型，那么 never 就是其他每个类型的子类型。可以把 never 理解为“兜底类型”。意味着 never 类型可以赋值给其他任何类型，在任何地方都能放心使用 never 类型的值。</p><table><thead><tr><th>类型</th><th>值</th></tr></thead><tbody><tr><td>null</td><td>缺少值</td></tr><tr><td>undefined</td><td>尚未赋值的变量</td></tr><tr><td>void</td><td>没有 return 语句的函数</td></tr><tr><td>never</td><td>永不返回的函数</td></tr></tbody></table><h3 id="_3-2-13-枚举" tabindex="-1"><a class="header-anchor" href="#_3-2-13-枚举" aria-hidden="true">#</a> 3.2.13 枚举</h3><p>美剧的作用是列举类型中包含的各个值。是一种无序数据结构，把键映射到值上。枚举可以理解为编译时键固定的对象，访问键时，TypeScript 将检查指定的键是否存在。</p><p>枚举分两种：字符串到字符串之间的映射和字符串到数字之间的映射。</p><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token comment">// TypeSript 自动为枚举中的各个成员推导对应的数字。</span>
<span class="token keyword">enum</span> Language <span class="token punctuation">{</span>
    English<span class="token punctuation">,</span>    <span class="token comment">// 0</span>
    Spanish<span class="token punctuation">,</span>    <span class="token comment">// 1</span>
    Russian     <span class="token comment">// 2</span>
<span class="token punctuation">}</span>

<span class="token keyword">let</span> en <span class="token operator">=</span> Language<span class="token punctuation">[</span><span class="token string">&quot;English&quot;</span><span class="token punctuation">]</span> <span class="token comment">// 0</span>
<span class="token keyword">let</span> ru <span class="token operator">=</span> Language<span class="token punctuation">.</span>Russian

</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container tip"><p class="custom-container-title">提示</p><p>按约定，枚举名称为大写的单数形式。枚举中的键也为大写。</p></div><p>一个枚举可以分成几次声明，TypeScript 将自动把各部分合并。 如果分开声明枚举，TypeSript 只能推导出其中一部分的值，因此最好显示赋值。</p><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token keyword">enum</span> Language <span class="token punctuation">{</span>
    English <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span>
    Spanish <span class="token operator">=</span> <span class="token number">1</span>
<span class="token punctuation">}</span>

<span class="token keyword">enum</span> Language <span class="token punctuation">{</span>
    Russian <span class="token operator">=</span> <span class="token number">2</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>成员的值可以经计算得出，而且不必为所有成员都赋值。</p><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token keyword">enum</span> Language <span class="token punctuation">{</span>
    English <span class="token operator">=</span> <span class="token number">100</span><span class="token punctuation">,</span>    
    Spanish <span class="token operator">=</span> <span class="token number">200</span> <span class="token operator">+</span> <span class="token number">300</span><span class="token punctuation">,</span>    
    Russian      <span class="token comment">// 经 TypeSript 推导出的值为 501 也就是上一个成员值得下一个数</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>枚举得值可以是字符串，甚至混用字符串和数字：</p><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token keyword">enum</span> Color <span class="token punctuation">{</span>
    Red <span class="token operator">=</span> <span class="token string">&#39;#c10000&#39;</span><span class="token punctuation">,</span>
    Blue <span class="token operator">=</span> <span class="token string">&#39;#007ac1&#39;</span><span class="token punctuation">,</span>
    Pink <span class="token operator">=</span> <span class="token number">0xc10050</span><span class="token punctuation">,</span>    <span class="token comment">// 十六进制</span>
    White <span class="token operator">=</span> <span class="token number">255</span>         <span class="token comment">// 十进制</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>TypeSript 既允许通过值访问枚举，也可以通过键访问。</p><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token keyword">enum</span> Color <span class="token punctuation">{</span>
  Red <span class="token operator">=</span> <span class="token string">&quot;#c10000&quot;</span><span class="token punctuation">,</span>
  Blue <span class="token operator">=</span> <span class="token string">&quot;#007ac1&quot;</span><span class="token punctuation">,</span>
  Pink <span class="token operator">=</span> <span class="token number">0xc10050</span><span class="token punctuation">,</span> <span class="token comment">// 十六进制</span>
  White <span class="token operator">=</span> <span class="token number">255</span><span class="token punctuation">,</span> <span class="token comment">// 十进制</span>
<span class="token punctuation">}</span>

<span class="token builtin">console</span><span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Color<span class="token punctuation">.</span>Red<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// #c10000</span>
<span class="token builtin">console</span><span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Color<span class="token punctuation">[</span><span class="token number">255</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// White</span>
<span class="token builtin">console</span><span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Color<span class="token punctuation">[</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span>

</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>Color[9] 不存在，但是 TypeScript 并不会报错。为了避免这种不安全的访问操作，可以通过 const enum 执行使用枚举的安全子集。</p><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token keyword">const</span> <span class="token keyword">enum</span> Language <span class="token punctuation">{</span>
  English<span class="token punctuation">,</span>
  Spanish<span class="token punctuation">,</span>
  Russian<span class="token punctuation">,</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>const enum 不允许反向查找。默认也不生成任何 JavaScript 代码，而是在用到枚举成员的地方内插对应的值。 （如：最终把 Language.English 替换成 0）</p><div class="custom-container tip"><p class="custom-container-title">TSC 标志：preserveConstEnums</p><p>const enum 内插值的行为在他人的代码中导入 const enum 可能会导致安全问题：假如使用他人的 const enum 时，他在我们编译后再次更改了 const enum。 当我们运行时使用的枚举与他的枚举值可能会有所不同。TypeScript 无法感知变化。</p><p>所以使用 const enum 时尽量避免内插，而且只在受自己控制的 TypeScript 程序中使用。如果想为 const enum 生成运行时代码，在 tsconfig.json 中把 TSC 选项 preserveConstEnums 配置为 true。</p></div><div class="custom-container warning"><p class="custom-container-title">注意</p><p>由于使用枚举极易导致安全问题，建议远离枚举。</p></div><h2 id="_3-3-小结" tabindex="-1"><a class="header-anchor" href="#_3-3-小结" aria-hidden="true">#</a> 3.3 小结</h2><p>TypeScript 内置大量类型。可以让 TypeScript 根据值推导类型，也可以显示注解类型。使用 const 时推导出的类型更具体，而 let 和 var 类型更一般化。 多数类型都分一般和具体两种类型，后者是前者的子类型。</p><table><thead><tr><th>类型</th><th>子类型</th></tr></thead><tbody><tr><td>boolean</td><td>Boolean 字面量</td></tr><tr><td>bigint</td><td>BigInt 字面量</td></tr><tr><td>number</td><td>Number 字面量</td></tr><tr><td>string</td><td>String 字面量</td></tr><tr><td>Symbol</td><td>unique symbol</td></tr><tr><td>object</td><td>Object 字面量</td></tr><tr><td>数组</td><td>元组</td></tr><tr><td>enum</td><td>const enum</td></tr></tbody></table></div><!----><footer class="page-meta"><!----><!----><!----></footer><nav class="page-nav"><a href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%202%20%E7%AB%A0%20TypeScript%20%E6%A6%82%E8%BF%B0.html" class="nav-link prev" aria-label="第 2 章 TypeScript 概述"><div class="hint"><span class="arrow left"></span>上一页</div><div class="link"><!---->第 2 章 TypeScript 概述</div></a><a href="/doc/readbook/%E3%80%8ATypeScript%E7%BC%96%E7%A8%8B%E3%80%8B/%E7%AC%AC%204%20%E7%AB%A0%20%E5%87%BD%E6%95%B0.html" class="nav-link next" aria-label="第 4 章 函数"><div class="hint">下一页<span class="arrow right"></span></div><div class="link">第 4 章 函数<!----></div></a></nav><!----><!----><!--]--></main><!--]--><!----><!--]--></div><!--]--><!----><!--]--></div>
    <script type="module" src="/doc/assets/app.41440b49.js" defer></script>
  </body>
</html>
